
#include <stdio.h>
#include "wm_hal.h"

// 定义用到的IO
#define PWR_PORT	GPIOB		// 如果没有电源控制脚则不用设置
#define PWR_PIN		GPIO_PIN_0	// 如果没有电源控制脚则不用设置
#define RST_PORT	GPIOB
#define RST_PIN		GPIO_PIN_1
#define CLK_PORT	GPIOB
#define CLK_PIN		GPIO_PIN_4
#define IO_PORT		GPIOB
#define IO_PIN		GPIO_PIN_2

UART_HandleTypeDef huart2;
_7816_HandleTypeDef h7816;

typedef struct
{
	uint8_t buf[66];
	uint32_t require_len;
	uint32_t current_len;
	volatile uint32_t finished;
	volatile uint32_t state;
} RxSturct;

static RxSturct rx;
static uint8_t uart_rx_buf[100] = {0};

void Error_Handler(void);
static void GPIO_Init(void);
static void UART2_Init(void);
static void _7816_Init(void);
static void RxDataProc(RxSturct *p);
static void DumpBuffer(char *name, uint8_t *buf, uint32_t len);

int main(void)
{
	SystemClock_Config(CPU_CLK_160M);
	printf("enter main\r\n");
	
	// 初始化power pin和reset pin为gpio output，必须在7816初始化之前，没有电源控制脚可以不用设置，
	GPIO_Init();
	// 初始化uart2，必须在7816初始化之前，且只能是uart2，其他uart不行
	UART2_Init();
	// 初始化7816
	_7816_Init();
	memset((uint8_t *)&rx, 0, sizeof(RxSturct));
	// 初始化uart中断接收，这里在选择了不定长接收，所以第三个参数传0
	HAL_UART_Receive_IT(&huart2, uart_rx_buf, 0);
	// 收发数据处理
	RxDataProc(&rx);
	while (1)
	{
		printf(".");
		HAL_Delay(1000);
	}
}

static void GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	__HAL_RCC_GPIO_CLK_ENABLE();

	GPIO_InitStruct.Pin = PWR_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(PWR_PORT, &GPIO_InitStruct);
	HAL_GPIO_WritePin(PWR_PORT, PWR_PIN, GPIO_PIN_RESET);
	
	GPIO_InitStruct.Pin = RST_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(RST_PORT, &GPIO_InitStruct);
	HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_RESET);

}

static void UART2_Init(void)
{
	huart2.Instance = UART2;
	// Init参数中需要设置Mode来使能发送和接收，其他参数不关心，只要是符合定义能检测通过即可。
	huart2.Init.Mode = UART_MODE_TX | UART_MODE_RX;
	huart2.Init.BaudRate = 115200;
	huart2.Init.WordLength = UART_WORDLENGTH_8B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	if (HAL_UART_Init(&huart2) != HAL_OK)
	{
		Error_Handler();
	}
}

static void _7816_Init(void)
{
	h7816.Instance = _7816;
	h7816.Init.Freq = 5000000;
	h7816.Init.Fd = 372;
	h7816.Init.LSB_MSB = _7816_LSB;
	h7816.Init.T0_1 = _7816_T0;
	h7816.Init.WaitTime = 0x1FF;
	h7816.Init.StopBits = _7816_STOPBITS_2;
	h7816.Init.PWR_Port = PWR_PORT;	// 如果没有电源控制脚则不用设置
	h7816.Init.PWR_Pin = PWR_PIN;	// 如果没有电源控制脚则不用设置
	h7816.Init.RST_Port = RST_PORT;
	h7816.Init.RST_Pin = RST_PIN;
	h7816.Init.CLK_Port = CLK_PORT;
	h7816.Init.CLK_Pin = CLK_PIN;
	h7816.Init.IO_Port = IO_PORT;
	h7816.Init.IO_Pin = IO_PIN;
	if (HAL_7816_Init(&h7816) != HAL_OK)
	{
		Error_Handler();
	}
}

static void RxDataProc(RxSturct *p)
{
	while(1)
	{
		switch(p->state)
		{
			case 0:
				p->require_len = 16;
				HAL_7816_ColReset(&h7816);
				printf("colreset over\r\n");
				break;
				
			case 1:
				DumpBuffer("ATR", p->buf, 16);
				if (p->buf[0] == 0x3B)
				{
					memset(p->buf, 0, sizeof(p->buf));
					p->buf[0] = 0xBF;
					p->buf[1] = 0x48;
					p->buf[2] = 0x02;
					p->buf[3] = 0x00;
					p->buf[4] = 0x24;
					p->require_len = 38;
					HAL_UART_Transmit(&huart2, p->buf, 5, 1000);
				}
				else
				{
					p->state = 0;
				}
				break;
				
			case 2:
				DumpBuffer("Ver", p->buf, 64);
				if (p->buf[0] == 0x48)
				{
					memset(p->buf, 0, sizeof(p->buf));
					p->buf[0] = 0xBF;
					p->buf[1] = 0x48;
					p->buf[2] = 0x0C;
					p->buf[3] = 0x00;
					p->buf[4] = 0x09;
					p->require_len = 11;
					HAL_UART_Transmit(&huart2, p->buf, 5, 1000);
				}
				break;
			
			case 3:
				DumpBuffer("Query", p->buf, 64);
				if (p->buf[0] == 0x48)
				{
					memset(p->buf, 0, sizeof(p->buf));
					p->buf[0] = 0xBF;
					p->buf[1] = 0xC6;
					p->buf[2] = 0x03;
					p->buf[3] = 0x00;
					p->buf[4] = 0x00;
					p->require_len = 1;
					HAL_UART_Transmit(&huart2, p->buf, 5, 1000);
				}	
				break;
				
			case 4:
				DumpBuffer("Query1", p->buf, 64);
				if (p->buf[0] == 0x6d)
				{
					memset(p->buf, 0, sizeof(p->buf));
					p->buf[60] = 0xBF;
					p->buf[61] = 0x58;
					p->buf[62] = 0x01;
					p->buf[63] = 0x01;
					p->buf[64] = 0x10;
					p->require_len = 18;
					HAL_UART_Transmit(&huart2, p->buf + 60, 5, 1000);
				}	
				break;
				
			case 5:
				DumpBuffer("RAND", p->buf, 64);
				if (p->buf[0] == 0x58)
				{
					while(1)
					{
						// .....
					}
				}
				break;
		}
		while (p->finished == 0);
		p->current_len = 0;
		p->finished = 0;
		p->state++;
		
	}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->RxXferCount > 0)
	{
		memcpy(rx.buf + rx.current_len, huart->pRxBuffPtr, huart->RxXferCount);
		rx.current_len += huart->RxXferCount;
		if(rx.current_len >= rx.require_len)
		{
			rx.finished = 1;
		}
	}
}

static void DumpBuffer(char *name, uint8_t *buf, uint32_t len)
{
	int i = 0;
	
	printf("%s:\r\n", name);
	for (i = 0; i < len; i++)
	{
		if((i % 16) == 0)
		{
			printf("\r\n");
		}
		printf("%02x ", buf[i]);
	}
	printf("\r\n");
}

void Error_Handler(void)
{
	while (1)
	{
	}
}

void assert_failed(uint8_t *file, uint32_t line)
{
	printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}